using Sage.WindowsProcess.Events;
using Sage.WindowsProcess.Models;
using System.Diagnostics;
using System.Runtime.Versioning;

namespace Sage.WindowsProcess
{
    /// <summary>
    /// ExternalProcessManager类的进程监控相关部分
    /// </summary>
    public partial class ExternalProcessManager
    {
        private System.DateTime _lastCpuTime = System.DateTime.MinValue;
        private TimeSpan _lastTotalProcessorTime = TimeSpan.Zero;
        private readonly Lock _monitorLock = new();
        private bool _monitoringEnabled;
        private int _monitoringIntervalMs = 1000; // 默认监控间隔为1秒
        private PerformanceCounter? _cpuCounter;

        /// <summary>
        /// 获取或设置进程监控的时间间隔（毫秒）。
        /// </summary>
        /// <exception cref="ArgumentException">当值小于或等于0时抛出。</exception>
        [SupportedOSPlatform("windows")]
        public int MonitoringIntervalMs
        {
            get => _monitoringIntervalMs;
            set
            {
                if (value <= 0)
                    throw new ArgumentException("监控间隔必须大于0。");

                _monitoringIntervalMs = value;

                // 如果监控正在进行，需要重新启动以应用新的间隔
                if (_monitoringEnabled && IsRunning)
                {
                    StopMonitoring();
                    StartMonitoring();
                }
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否启用进程监控。
        /// </summary>
        [SupportedOSPlatform("windows")]
        public bool MonitoringEnabled
        {
            get => _monitoringEnabled;
            set
            {
                if (_monitoringEnabled != value)
                {
                    _monitoringEnabled = value;
                    if (_monitoringEnabled && IsRunning)
                    {
                        StartMonitoring();
                    }
                    else
                    {
                        StopMonitoring();
                    }
                }
            }
        }

        /// <summary>
        /// 启动进程监控。
        /// </summary>
        [SupportedOSPlatform("windows")]
        public void StartMonitoring()
        {
            lock (_monitorLock)
            {
                if (_monitoringEnabled && IsRunning && _monitoringTimer == null)
                {
                    try
                    {
                        // 初始化CPU计数器
                        InitializeCpuCounter();

                        // 创建监控定时器
                        _monitoringTimer = new Timer(MonitorProcess, null, 0, _monitoringIntervalMs);
                    }
                    catch (Exception ex)
                    {
                        OnProcessError(new ProcessErrorEventArgs($"启动进程监控失败: {ex.Message}", ex));
                    }
                }
            }
        }

        /// <summary>
        /// 如果监控已启用，则启动进程监控。
        /// </summary>
        [SupportedOSPlatform("windows")]
        private void StartMonitoringIfEnabled()
        {
            if (_monitoringEnabled)
            {
                StartMonitoring();
            }
        }

        /// <summary>
        /// 停止进程监控。
        /// </summary>
        public void StopMonitoring()
        {
            lock (_monitorLock)
            {
                if (_monitoringTimer != null)
                {
                    var timer = _monitoringTimer;
                    _monitoringTimer = null; // 先设置为null，防止重复处置
                    timer.Change(Timeout.Infinite, Timeout.Infinite); // 停止定时器触发
                    timer.Dispose(); // 然后处置
                }

                DisposeCpuCounter();
            }
        }

        /// <summary>
        /// 初始化CPU使用率计数器。
        /// </summary>
        [SupportedOSPlatform("windows")]
        private void InitializeCpuCounter()
        {
            // 先释放现有计数器
            DisposeCpuCounter();

            if (_process != null && !_process.HasExited)
            {
                try
                {
                    _cpuCounter ??= new PerformanceCounter("Process", "% Processor Time", _process.ProcessName);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"初始化CPU计数器失败: {ex.Message}");
                    // 不抛出异常，因为这不是关键错误
                }
            }
        }

        /// <summary>
        /// 释放CPU使用率计数器。
        /// </summary>
        private void DisposeCpuCounter()
        {
            if (_cpuCounter != null)
            {
                try
                {
                    var counter = _cpuCounter;
                    _cpuCounter = null; // 先设置为null，防止重复处置

                    // 仅在Windows平台上调用Close方法
                    if (OperatingSystem.IsWindows())
                    {
                        counter.Close();
                    }

                    counter.Dispose();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"释放CPU计数器时发生错误: {ex.Message}");
                    // 不抛出异常
                }
            }
        }

        /// <summary>
        /// 监控进程并触发状态更新事件。
        /// </summary>
        [SupportedOSPlatform("windows")]
        private void MonitorProcess(object? state)
        {
            if (!IsRunning || _process == null) return;

            try
            {
                // 刷新进程信息
                _process.Refresh();

                if (_process.HasExited) return;

                // 获取内存使用量
                long memoryUsageBytes = _process.WorkingSet64;

                // 获取CPU使用率
                double cpuUsagePercent = GetCpuUsage();

                // 获取运行时间
                TimeSpan runningTime = System.DateTime.Now - _process.StartTime;

                // 获取线程数
                int threadCount = _process.Threads.Count;

                // 创建状态事件参数
                var statusArgs = new ProcessStatusEventArgs(
                    _process,
                    cpuUsagePercent,
                    memoryUsageBytes,
                    runningTime,
                    threadCount
                );

                // 触发状态更新事件
                OnProcessStatusUpdated(statusArgs);
            }
            catch (Exception ex)
            {
                // 监控过程中的错误不应该导致应用程序崩溃，只记录错误
                Debug.WriteLine($"进程监控错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取进程的CPU使用率。
        /// </summary>
        /// <returns>CPU使用率百分比。</returns>
        [SupportedOSPlatform("windows")]
        private double GetCpuUsage()
        {
            try
            {
                if (_process == null || _process.HasExited) return 0;

                // 使用PerformanceCounter获取CPU使用率
                if (_cpuCounter != null)
                {
                    try
                    {
                        return Math.Round(_cpuCounter.NextValue() / Environment.ProcessorCount, 2);
                    }
                    catch
                    {
                        // 如果PerformanceCounter失败，回退到手动计算
                    }
                }

                // 手动计算CPU使用率
                System.DateTime now = System.DateTime.Now;
                TimeSpan totalProcessorTime = _process.TotalProcessorTime;

                if (_lastCpuTime != System.DateTime.MinValue)
                {
                    TimeSpan elapsedTime = now - _lastCpuTime;
                    TimeSpan cpuUsedTime = totalProcessorTime - _lastTotalProcessorTime;

                    double cpuUsagePercent = cpuUsedTime.TotalMilliseconds /
                                           (elapsedTime.TotalMilliseconds * Environment.ProcessorCount) * 100;

                    // 确保结果在有效范围内
                    cpuUsagePercent = Math.Max(0, Math.Min(100, cpuUsagePercent));

                    _lastCpuTime = now;
                    _lastTotalProcessorTime = totalProcessorTime;

                    return Math.Round(cpuUsagePercent, 2);
                }

                _lastCpuTime = now;
                _lastTotalProcessorTime = totalProcessorTime;
                return 0;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取进程的当前状态信息。
        /// </summary>
        /// <returns>包含进程状态信息的对象，如果进程未运行则为null。</returns>
        [SupportedOSPlatform("windows")]
        public ProcessStatusInfo? GetProcessStatus()
        {
            if (!IsRunning || _process == null) return null;

            try
            {
                _process.Refresh();

                if (_process.HasExited) return null;

                return new ProcessStatusInfo
                {
                    ProcessId = _process.Id,
                    ProcessName = _process.ProcessName,
                    MemoryUsageBytes = _process.WorkingSet64,
                    CpuUsagePercent = GetCpuUsage(),
                    RunningTime = System.DateTime.Now - _process.StartTime,
                    ThreadCount = _process.Threads.Count,
                    HandleCount = _process.HandleCount,
                    StartTime = _process.StartTime,
                    Responding = _process.Responding
                };
            }
            catch
            {
                return null;
            }
        }
    }
}
